#include <cv.h>
#include <highgui.h>
#include <stdio.h>
#include <time.h>
#include <ctype.h>
#include "../../IA/src/OutilsEntree.h"
#include "acquisition-outils.h"
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

static CvScalar colorred;
static CvScalar colorgreen;
static CvScalar colorblue;

// Descripteurs du pipe permettant de communiquer avec l'IA
static int numpipe[2];

// Temps
static double timeprecedent;
static double timeactuel;

// Tableaux de stockage des objets détectés
static const int nbmaxBleu	= 4;
static int nbBleu;
static int nbBleuprecedent;
static positionRectangle* objetsBleu ;
static positionRectangle* objetsBleuprecedent ;
static const int nbmaxRouge	= 1;
static int nbRouge;
static int nbRougeprecedent;
static positionRectangle* objetsRouge;
static positionRectangle* objetsRougeprecedent;

static orientationObjet notreCoteTerrain = AUCUN;

static int trouverlimitesterrain(IplImage* src, IplImage* dst, IplImage* color_dst, 
								ligneThetaRho lignes[], int* nbLignes, int nbmaxLignes)
// trouverlimitesterrain analyse l'image source et en déduit les lignes vertes
// <src> : image source, en vert
// <dst> : image canny, pas très utile
// <color_dst> : image_canny, en RGB
// <lignes[]> : tableau des lignes de sortie
// <nbLignes> : nombre de lignes trouvées
// <nbmaxLignes> : nb max de lignes à chercher
{
    if( !(src!= 0) )
    {
        return -1;
    }
    else
    {
	    CvMemStorage* storage = cvCreateMemStorage(0);
	    CvSeq* lines = 0;
	    int i;
	    cvCanny( src, dst, 50, 200, 3 );
	    cvCvtColor( dst, color_dst, CV_GRAY2BGR );

        lines = cvHoughLines2( dst, storage, CV_HOUGH_STANDARD, 1, CV_PI/180, 100, 0, 0 );
        *nbLignes = 0;
        for( i = 0; i < MIN(lines->total,100); i++ )
        {
            float* line = (float*)cvGetSeqElem(lines,i);
            //ligneThetaRho
            lignes[*nbLignes].rho = line[0];
            lignes[*nbLignes].theta = line[1];
            (*nbLignes)++;
            if (*nbLignes>=nbmaxLignes)
            	break;
        }
    	cvReleaseMemStorage(&storage);
    }
    return 0;
}
    		
int trouverlesbords(IplImage* brgframe, CvPoint coins[], int * nbCoins)
// trouverlesbords détecte les bords de l'image
//					fonctionnemeent :
//						utilise l'image
//						la transforme en vert
//						récupère toutes les lignes la composant
//						cherche les lignes extremes, en déduit les points d'intersection
//						
// <coins> : tableau des coins du terrain
//				<coins> doit etre alloué !!!
// 				coins[0] = haut gauche
// 				coins[1] = haut droit
// 				coins[2] = bas  droit
// 				coins[3] = bas  gauche
{
	if (!brgframe)
	{
		return -1;
	}
	//Copies de l’image pour les transformations…
	IplImage* hsvframe 		= cvCreateImage( cvGetSize(brgframe), IPL_DEPTH_8U, 3 );
	IplImage* resultvert	= cvCreateImage( cvGetSize(brgframe), IPL_DEPTH_8U, 3 );
	IplImage* vertframe		= cvCreateImage( cvGetSize(brgframe), 8			  , 1 );
	IplImage* vertdilate	= cvCreateImage( cvGetSize(brgframe), 8			  , 1 );
    IplImage* vertcvcanny	= cvCreateImage( cvGetSize(brgframe), 8			  , 1 );
	IplImage* vertlimites	= cvCreateImage( cvGetSize(brgframe), 8			  , 3 );
	
	int nbVert;
	int nbmaxVert	= 10;
	(*nbCoins) = 0;
	ligneThetaRho objetsVert [nbmaxVert ];
    
    ligneThetaRho lignehaut, lignebas, lignegauche, lignedroite;
    lignehaut.trouve = KO;lignebas.trouve = KO;
    lignegauche.trouve = KO;lignedroite.trouve = KO;
	
	cvCvtColor( brgframe, hsvframe , CV_BGR2HSV );
	traitervert (hsvframe);
	cvCvtColor( hsvframe, resultvert , CV_HSV2RGB );
	cvCvtColor( resultvert , resultvert , CV_RGB2BGR );
	int tmp;
	
	cvCvtColor(resultvert, vertframe, CV_BGR2GRAY);
    lignehaut.trouve = KO;lignebas.trouve = KO;
    lignegauche.trouve = KO;lignedroite.trouve = KO;
	
	IplConvKernel* element = cvCreateStructuringElementEx( 13, 13, 6, 6, CV_SHAPE_RECT, NULL );
	
	cvDilate(vertframe , vertdilate, element, 1 );
	cvErode (vertdilate, vertframe , element, 1 );
	cvReleaseStructuringElement(&element);
	trouverlimitesterrain(vertframe, vertcvcanny, vertlimites, objetsVert, &nbVert, nbmaxVert);
	int numlignehaut = -1;
	int numlignegauche = -1;
	
	if ( (tmp = trouverunelimite(objetsVert, nbVert, HAUT, numlignehaut)) != -1)
	{
		lignehaut = objetsVert[tmp];
		numlignehaut = tmp;
		lignehaut.trouve = OK;
	}
	if ( (tmp = trouverunelimite(objetsVert, nbVert, BAS, numlignehaut)) != -1)
	{
		lignebas = objetsVert[tmp];
		numlignehaut = tmp;
		lignebas.trouve = OK;
	}
	if ( (tmp = trouverunelimite(objetsVert, nbVert, GAUCHE, numlignegauche)) != -1)
	{
		lignegauche = objetsVert[tmp];
		numlignegauche = tmp;
		lignegauche.trouve = OK;
	}
	if ( (tmp = trouverunelimite(objetsVert, nbVert, DROITE, numlignegauche)) != -1)
	{
		lignedroite = objetsVert[tmp];
		numlignegauche = tmp;
		lignedroite.trouve = OK;
	}
	
	if (lignehaut.trouve == OK && lignegauche.trouve == OK)
	{
		(*nbCoins)++;
		calculintersection(lignehaut, lignegauche, (coins + 0));
	}
	if (lignehaut.trouve == OK && lignedroite.trouve == OK)
	{
		(*nbCoins)++;
		calculintersection(lignehaut, lignedroite, (coins + 1));
	}
	if (lignebas.trouve == OK && lignedroite.trouve == OK)
	{
		(*nbCoins)++;
		calculintersection(lignebas, lignedroite, (coins + 2));
	}
	if (lignebas.trouve == OK && lignegauche.trouve == OK)
	{
		(*nbCoins)++;
		calculintersection(lignebas, lignegauche, (coins + 3));
	}
	
	//Libérer l’espace des images
	cvReleaseImage( &hsvframe	);
	cvReleaseImage( &resultvert );
	cvReleaseImage( &vertframe	);
	cvReleaseImage( &vertdilate	);
	cvReleaseImage( &vertcvcanny);
	cvReleaseImage( &vertlimites);
	
    return 0;
}

int initialiserobjets()
// initialise et alloue les vaiables globales
{
	int i;
	nbBleu = 0;
	nbRouge = 0;
	nbBleuprecedent = 0;
	nbRougeprecedent = 0;
	objetsBleu			= (positionRectangle*) malloc( nbmaxBleu  * sizeof(positionRectangle) );
	objetsRouge			= (positionRectangle*) malloc( nbmaxRouge * sizeof(positionRectangle) );
	objetsBleuprecedent = (positionRectangle*) malloc( nbmaxBleu  * sizeof(positionRectangle) );
	objetsRougeprecedent= (positionRectangle*) malloc( nbmaxRouge * sizeof(positionRectangle) );
	for (i=0 ; i<nbmaxBleu ; i++)
	{
		objetsBleu[i].center = cvPoint(0, 0);
		objetsBleu[i].width = 0;
		objetsBleu[i].height = 0;
		objetsBleuprecedent[i].center = cvPoint(0, 0);
		objetsBleuprecedent[i].width = 0;
		objetsBleuprecedent[i].height = 0;
	}
	for (i=0 ; i<nbmaxRouge ; i++)
	{
		objetsRouge[i].center = cvPoint(0, 0);
		objetsRouge[i].width = 0;
		objetsRouge[i].height = 0;
		objetsRougeprecedent[i].center = cvPoint(0, 0);
		objetsRougeprecedent[i].width = 0;
		objetsRougeprecedent[i].height = 0;
	}
	return 0;
}

void fairecorrespondreobjets()
// NE MARCHE PAS !!
// aurait du servir à réarranger les objets détectés dans le meme ordre que ceux de l'image precedente
// et considérer les objets non détectés comme n'ayant pas bougé
{
	if (nbRouge == 0)
	{
		objetsRouge[0] = objetsRougeprecedent[0];
	}
	int matchobjetsbleu[nbmaxBleu];
	positionRectangle objetsBleutemp[nbmaxBleu];
	int i, j;
	int tmpdeja;
	int nbcarremin;
	int dejautilise;
	float distancemin;
	for (i=0; i<nbmaxBleu; i++)
	{
		matchobjetsbleu[i] = -1;
	}
	for (i=0; i<nbmaxBleu; i++)
	{
		nbcarremin=0;
		distancemin = 1000 * 1000.;
		for (j=0; j<nbmaxBleu;j++)
		{
			dejautilise = 0;
			for (tmpdeja = 0; tmpdeja<nbmaxBleu; tmpdeja++)
			{
				if(matchobjetsbleu[tmpdeja] == j)
				{
					dejautilise =1;
					break;
				}
			}
			float nouvelleDistanceMin = distancecarre(objetsBleu[i], objetsBleuprecedent[j]);
			if (dejautilise == 0 && distancemin < nouvelleDistanceMin)
			{
				distancemin = nouvelleDistanceMin;
				nbcarremin = j;
			}
		}
		matchobjetsbleu[i] = j;
	}
	for (i=0; i<nbBleu; i++)
	{
		objetsBleutemp[i] = objetsBleu[matchobjetsbleu[i]];
	}
	for (i=nbBleu; i<nbmaxBleu; i++)
	{
		objetsBleutemp[i] = objetsBleuprecedent[i];
	}
	for (i=0; i<nbmaxBleu; i++)
	{
		objetsBleu[i] = objetsBleutemp[i];
	}
}

int sauvegarderobjets()
// sauver les objets détectés pour ne pas les écraser
{
	int i;
	for (i=0 ; i<nbmaxBleu ; i++)
	{
		objetsBleuprecedent[i] = objetsBleu[i];
	}
	for (i=0 ; i<nbmaxRouge ; i++)
	{
		objetsRougeprecedent[i] = objetsRouge[i];
	}
	nbBleuprecedent = nbBleu;
	nbRougeprecedent = nbRouge;
	return 0;
}

int relacherobjets()
// déasallouer les mémoires des variables globales
{
	free( objetsBleu 			);
	free( objetsRouge 			);
	free( objetsBleuprecedent 	);
	free( objetsRougeprecedent 	);
	return 0;
}

int initialiserlimites(IplImage* brgframe, CvPoint2D32f pts_input[], CvPoint2D32f pts_output[])
// initialise les matrices de détection des points
{
    pts_input[0] = cvPointTo32f(cvPoint(0, 0));
    pts_input[1] = cvPointTo32f(cvPoint(0, 0));
    pts_input[2] = cvPointTo32f(cvPoint(0, 0));
    pts_input[3] = cvPointTo32f(cvPoint(0, 0));
	
    pts_output[0] = cvPointTo32f(cvPoint(0				, 0));
    pts_output[1] = cvPointTo32f(cvPoint(brgframe->width, 0));
    pts_output[2] = cvPointTo32f(cvPoint(brgframe->width, brgframe->height));
    pts_output[3] = cvPointTo32f(cvPoint(0				, brgframe->height));
    
	return 0;
}

int recupererlimites(CvPoint pts_coins[], CvPoint2D32f pts_input[])
// engrange les valeurs des limites pour moyenner
{
	pts_input[0].x += pts_coins[0].x;
	pts_input[0].y += pts_coins[0].y;
	
	pts_input[1].x += pts_coins[1].x;
	pts_input[1].y += pts_coins[1].y;
	
	pts_input[2].x += pts_coins[2].x;
	pts_input[2].y += pts_coins[2].y;
	
	pts_input[3].x += pts_coins[3].x;
	pts_input[3].y += pts_coins[3].y;
    
	return 0;
}
int finirtraiterlimites(CvPoint2D32f pts_input[], int nbimages, CvPoint2D32f pts_output[], CvMat* mmat)
// moyenne les valeurs des bords trouvés
{
	double xg, xd, yg, yd;
	pts_input[0].x = pts_input[0].x / nbimages; pts_input[0].y = pts_input[0].y / nbimages;
	pts_input[1].x = pts_input[1].x / nbimages; pts_input[1].y = pts_input[1].y / nbimages;
	pts_input[2].x = pts_input[2].x / nbimages; pts_input[2].y = pts_input[2].y / nbimages;
	pts_input[3].x = pts_input[3].x / nbimages; pts_input[3].y = pts_input[3].y / nbimages;
    
    trouvermatriceperspective(pts_input, pts_output, mmat);

	xg = pts_input[0].x - pts_input[3].x;
	yg = pts_input[0].y - pts_input[3].y;
	xd = pts_input[1].x - pts_input[2].x;
	yd = pts_input[1].y - pts_input[2].y;
	if ( (xg * xg + yg * yg) > ( xd * xd + yd * yd) )
	{
		printf("<finirtraiterlimites> : notreCoteTerrain = GAUCHE\n");
		notreCoteTerrain = GAUCHE;
	}
	else
	{
		printf("<finirtraiterlimites> : notreCoteTerrain = DROITE\n");
		notreCoteTerrain = DROITE;
	}
	return 0;
}
    		
int traitementacquisition(IplImage* brgframe)
// traite l'image pour détecter les objets khepera et balle
// <brgframe> : image dont la perspective a déjà été changée
{
	if (!brgframe)
	{
		return -1;
	}
	//Copies de l’image pour les transformations…
	IplImage* hsvframe 		= cvCreateImage( cvGetSize(brgframe), IPL_DEPTH_8U, 3 );
	IplImage* resultbleu	= cvCreateImage( cvGetSize(brgframe), IPL_DEPTH_8U, 3 );
	IplImage* resultrouge	= cvCreateImage( cvGetSize(brgframe), IPL_DEPTH_8U, 3 );
    IplImage* motionbleu	= cvCreateImage( cvGetSize(brgframe), 8			  , 3 );
    IplImage* motionrouge	= cvCreateImage( cvGetSize(brgframe), 8			  , 3 );
	
	//Conversion BGR -> HSV
	cvCvtColor( brgframe, hsvframe , CV_BGR2HSV );
	traiterbleu (hsvframe);
	cvCvtColor( hsvframe, resultbleu, CV_HSV2RGB );
	cvCvtColor( resultbleu, resultbleu, CV_RGB2BGR );
	//Conversion BGR -> HSV
	cvCvtColor( brgframe, hsvframe , CV_BGR2HSV );
	traiterrouge(hsvframe);
	cvCvtColor( hsvframe, resultrouge, CV_HSV2RGB );
	cvCvtColor( resultrouge, resultrouge, CV_RGB2BGR );
	
	//Erosion puis dilatation pour éliminer les bruits
	IplImage* rougeErode = cvCreateImage( cvGetSize(brgframe), IPL_DEPTH_8U, 3 );
	IplImage* bleuErode  = cvCreateImage( cvGetSize(brgframe), IPL_DEPTH_8U, 3 );
	IplConvKernel* elementrouge = cvCreateStructuringElementEx(  8,  8, 4, 4, CV_SHAPE_RECT, NULL );
	IplConvKernel* elementbleu  = cvCreateStructuringElementEx(  5,  5, 2, 2, CV_SHAPE_RECT, NULL );
	
	// Erosion puis dilatation sur le noir = dilatation puis erosion sur le blanc
	cvErode (resultbleu  , bleuErode   , elementbleu, 1 );
	cvDilate(bleuErode   , resultbleu  , elementbleu, 1 );
	// Erosion puis dilatation sur le noir = dilatation puis erosion sur le blanc
	cvErode (resultrouge , rougeErode  , elementrouge, 1 );
	cvDilate(rougeErode  , resultrouge , elementrouge, 1 );
	
	cvReleaseStructuringElement(&elementrouge);
	cvReleaseStructuringElement(&elementbleu);
	cvReleaseImage(&rougeErode);
	cvReleaseImage(&bleuErode );
	//Fin Erosion puis dilatation
    
    cvZero( motionbleu  );
    cvZero( motionrouge );
    motionbleu ->origin = resultbleu ->origin;
    motionrouge->origin = resultrouge->origin;
    update_mhi( resultbleu , motionbleu , 30, TAILLE_MIN_BALLE  , TAILLE_MAX_BALLE  , objetsBleu , &nbBleu , nbmaxBleu );
    update_mhi( resultrouge, motionrouge, 30, TAILLE_MIN_KHEPERA, TAILLE_MAX_KHEPERA, objetsRouge, &nbRouge, nbmaxRouge);
    
	int tmp;
	float coeff_x = (TERRAIN_LARGEUR * 1.) / brgframe->width ;
	float coeff_y = (TERRAIN_HAUTEUR * 1.) / brgframe->height;
	//fairecorrespondreobjets(); //TODO : Faire correpondre les objets trouvés aux derniers objets trouvés, grace à la distance minimale
	
	// TODO : amélioration à apporter : si coté gauche, inverser x ?...
	for (tmp=0; tmp<nbmaxRouge; tmp++)
	{
        cvCircle( brgframe, objetsRouge[tmp].center, cvRound((objetsRouge[tmp].width + objetsRouge[tmp].height) /2), colorred, 3, CV_AA, 0 );
		
		positionObjetEntree objetBalle;
		objetBalle.x = objetsRouge[tmp].center.x * coeff_x;
		objetBalle.y = objetsRouge[tmp].center.y * coeff_y;
		objetBalle.vitesse_x = (objetsRouge[tmp].center.x - objetsRougeprecedent[tmp].center.x + 0.) * coeff_x / (timeactuel - timeprecedent);
		objetBalle.vitesse_y = (objetsRouge[tmp].center.y - objetsRougeprecedent[tmp].center.y + 0.) * coeff_y / (timeactuel - timeprecedent);
		objetBalle.objet = BALLE;
		objetBalle.numero = 0;
		write(numpipe[1], &objetBalle, sizeof(positionObjetEntree) );
	}
	int num_a_nous = 0;
	int num_a_eux  = 0;
	for (tmp=0; tmp<nbmaxBleu; tmp++)
	{
        cvCircle( brgframe, objetsBleu[tmp].center, cvRound((objetsBleu[tmp].width + objetsBleu[tmp].height) /2), colorblue, 3, CV_AA, 0 );
		positionObjetEntree objetKhepera;
		objetKhepera.x = objetsBleu[tmp].center.x * coeff_x;
		objetKhepera.y = objetsBleu[tmp].center.y * coeff_y;
		objetKhepera.vitesse_x = (objetsBleu[tmp].center.x - objetsBleuprecedent[tmp].center.x + 0.) * coeff_x / (timeactuel - timeprecedent);
		objetKhepera.vitesse_y = (objetsBleu[tmp].center.y - objetsBleuprecedent[tmp].center.y + 0.) * coeff_y / (timeactuel - timeprecedent);
		if ( ((objetsBleu[tmp].center.x < TERRAIN_LARGEUR / 2.) && ( notreCoteTerrain == DROITE )) ||
			 ((objetsBleu[tmp].center.x > TERRAIN_LARGEUR / 2.) && ( notreCoteTerrain == GAUCHE )) )
		// khepera pas de notre coté
		{
			num_a_eux++;
			objetKhepera.objet = KHEPERA_ADVERSE;
			objetKhepera.numero = num_a_eux;
		}
		else
		//khepera de notre coté
		{
			num_a_nous++;
			objetKhepera.objet = KHEPERA_A_NOUS;
			objetKhepera.numero = num_a_nous;
		}
		write(numpipe[1], &objetKhepera, sizeof(positionObjetEntree) );
	}
	
	//Libérer l’espace des images
	cvReleaseImage( &hsvframe	);
	cvReleaseImage( &resultbleu	);
	cvReleaseImage( &resultrouge);
	cvReleaseImage( &motionbleu	);
	cvReleaseImage( &motionrouge);
	
	sauvegarderobjets();
    return 0;
}
	
int acquisition(int pipedescriptor[], int argc, char** argv)
// acquisition est la fonction principale
// fonctionnement :
//		récupère la caméra ou le fichier vidéo à analyser
//		initialise les objets et mémoires de stockage
//		ne touche pas les premières images (sur les vidéos, premières secondes inexploitables)
//		fait la moyenne des limites trouvées sur plusieurs images récupérées
//		en déduit la matrice de changement de perspective
//		pour chaque nouvelle image, la changer de perspective puis la traiter
//		lors de l'appui sur "ECHAP", envoie dans le pipe d'un objet ayant le type "AUTRE" (= fin de l'application)
{
	IplImage* brgFrame;
	CvMat* mmat = cvCreateMat(3,3,CV_32FC1);
	int nbImagesBords = 20;
	int nbImages_tmp = 0;
	int nbCoins = 0;
	int i;
	char touche;
	colorred   = CV_RGB(255,0,0);
	colorgreen = CV_RGB(0,255,0);
	colorblue  = CV_RGB(0,0,255);
	CvPoint      pts_coins      [4];
	CvPoint2D32f pts_input		[4];
	CvPoint2D32f pts_output     [4];
	
	IplImage* bordsframe;
	IplImage* perspectiveframe;
	
	numpipe[0] = pipedescriptor[0];
	numpipe[1] = pipedescriptor[1];
	close(numpipe[0]);
	
	creerfenetresperspective(2);
	cvWaitKey(10);
	if (argc != 1)
	{
    	CvCapture* camera = 0;
    	if( argc == 1 || (argc == 2 && strlen(argv[1]) == 1 && isdigit(argv[1][0])))
    	{
        	camera = cvCaptureFromCAM( argc == 2 ? argv[1][0] - '0' : 0 );
            printf("<acquisition> : caméra <%d>\n", argv[1][0] - '0');
    	}
    	else if( argc == 2 )
    	{
        	camera = cvCaptureFromFile( argv[1] );
            printf("<acquisition> : caméra <%s>\n", argv[1] );
    	}
    	if( camera )
    	{
            printf("<acquisition> : caméra OK\n");
			//Capturer une image
			cvGrabFrame( camera );
			//Aller chercher l’image sous format IplImage
			brgFrame 		= cvRetrieveFrame( camera );
            initialiserlimites(brgFrame, pts_input, pts_output);
            
	        for(i = 0; i < 10;i++) // l'image ne varie pas dans les 20 premières images
	        {
				cvGrabFrame( camera );
				brgFrame 		= cvRetrieveFrame( camera );
				touche = cvWaitKey(10);
				cvShowImage( wdnbrg			, brgFrame			);
                if( touche == 27 )
                    break;
	        }
	        
			timeactuel = (double)clock()/CLOCKS_PER_SEC; // initialisation du compteur de temps
	        for(nbImages_tmp = 0; nbImages_tmp <nbImagesBords;) // pas nbImages_tmp++ : seulement si l'image est correcte
	        {
				//Capturer une image
				cvGrabFrame( camera );
				//Aller chercher l’image sous format IplImage
				brgFrame 		= cvRetrieveFrame( camera );
				if ( trouverlesbords(brgFrame, pts_coins, &nbCoins) == -1 )
					continue;
				bordsframe = cvCloneImage(brgFrame);
				if (nbCoins == 4)
				{
					nbImages_tmp++;				// nbImages_tmp++
					recupererlimites(pts_coins, pts_input);
					for (i=0; i<4; i++)
					{
						cvCircle( bordsframe, pts_coins[i], 7, colorblue, -1, 8, 0 );
					}
				}
				cvShowImage( wdnbrg			, brgFrame			);
				cvShowImage( wdnbords		, bordsframe		);
				touche = cvWaitKey(10);
				cvReleaseImage(&bordsframe);
                if( touche == 27 )
                    break;
	        }
	        finirtraiterlimites(pts_input, nbImages_tmp, pts_output, mmat);
			
            IplImage* bordsframe;
			bordsframe = cvCloneImage(brgFrame);
			for (i=0; i<4; i++)
			{
				cvCircle( bordsframe, cvPoint((int) pts_input[i].x, (int) pts_input[i].y), 7, colorblue, -1, 8, 0 );
			}
			perspectiveframe = cvCreateImage( cvGetSize(brgFrame), IPL_DEPTH_8U, 3 );
			cvShowImage( wdnbrg			, brgFrame			);
			cvShowImage( wdnbords		, bordsframe		);
			
			cvReleaseImage(&bordsframe);
            initialiserobjets();
	        for(;;)
	        {
				//Capturer une image
				cvGrabFrame( camera );
				//Aller chercher l’image sous format IplImage
				brgFrame		 = cvRetrieveFrame( camera );
				arrangerimage(brgFrame, perspectiveframe, mmat);
				timeprecedent = timeactuel;
				timeactuel    = (double)clock()/CLOCKS_PER_SEC;
				printf("<acquisition> : temps entre deux images : %f\n", timeactuel - timeprecedent);
                if (traitementacquisition(perspectiveframe) == -1)
                {
                	printf("<acquisition> : erreur lors du traitement de l'image\n");
                }
				
				cvShowImage( wdnbrg			, brgFrame			);
				cvShowImage( wdnperspective	, perspectiveframe	);
				touche = cvWaitKey(10);
                if( touche >= 0 )
                    break;
	        }
			relacherobjets();
			printf("<acquisition> : fin du for(;;)\n");
			cvReleaseImage(&perspectiveframe);
	        
			//Libérer la caméra
			cvReleaseCapture( &camera	);
			//cvReleaseImage( &brgFrame ); //// Not release brgFrame !!!!!!!!!
    	}
    	else
    	{
            printf("<acquisition> : pas de caméra\n");
    	}
	}
    cvReleaseMat(&mmat);
	detruirefenetresperspective();
	positionObjetEntree objetFIN;
	objetFIN.x = 0.;
	objetFIN.y = 0.;
	objetFIN.vitesse_x = 0.;
	objetFIN.vitesse_y = 0.;
	objetFIN.objet = AUTRE;
	objetFIN.numero = 42;
	write(numpipe[1], &objetFIN, sizeof(positionObjetEntree) );
	close(numpipe[1]);
	return 0;
}
